package com.lee.rabbitmq.confirm.addConfirmListener;

import com.lee.rabbitmq.util.RabbitMqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;

import java.io.IOException;

/**
 * 批量确认模式
 *
 * @author Lee
 * @createDate 2021/12/16 13:45
 */
public class Send {
    public static void main(String[] args) {
        Connection connection = RabbitMqUtil.getConnection();
        Channel channel = null;
        try {
            channel = connection.createChannel();
            //声明队列
            channel.queueDeclare("confirmQueue",true,false,false,null);


            channel.exchangeDeclare("directConfirmExchange","direct",true);


            channel.queueBind("confirmQueue","directConfirmExchange","confirmRoutingKey");

            //启动发送者确认模式
            channel.confirmSelect();


            /**
             * 异步消息确认监听器，需要在发送消息前启动
             */
            channel.addConfirmListener(new ConfirmListener() {
                /**
                 * 消息确认后回调方法
                 * 注意:
                 *  如果参数b为true则表示本次确认同时确认了多条消息，消息等于当前
                 *  参数l（消息编号）的所有消息全部被确认
                 *  如果为false则表示只有当前编号的消息被确认
                 * @param l 被确认的消息的编号,从1开始自动递增用于标记当前是第几个消息
                 * @param b 当前消息是否同时确认的个数
                 */
                public void handleAck(long l, boolean b) throws IOException {
                    System.out.println("消息被确认了---消息编号:"+l+"是否确认了多条:"+b);
                }
                /**
                 * 消息没有确认后回调方法
                 * 如果这个方法被执行表示当前的消息没有被确认需要进行消息补发
                 * 注意:
                 *  如果参数b为true则表示小于当前编号的所有的消息可能都没有发送成功需要进行消息的补发
                 *  如果参数b为false则表示当前编号的消息没发送成功需要进行补发
                 * @param l 没有确认的消息的编号,从1开始自动递增用于标记当前是第几个消息
                 * @param b 当前消息是否同时没有确认的个数
                 */
                public void handleNack(long l, boolean b) throws IOException {
                    System.out.println("消息没有确认---消息编号:"+l+"没确认了多条:"+b);
                }
            });

            for (int i = 1; i < 1001; i++) {
                Thread.sleep(1);
                String message = "异步监听发送方确认模式事务测试消息"+i+"！";
                channel.basicPublish("directConfirmExchange","confirmRoutingKey",null,message.getBytes("utf-8"));
            }

            System.out.println("消息发送成功!");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            RabbitMqUtil.close(connection,channel);
        }
    }
}
